Telco é uma empresa de telecomunicações americana, reconhecida por serviços residenciais como televisão por assinatura, acesso à internet e telefonia fixa.
Em uma reunião da empresa entre os gerentes e CEO, foi averiguado que taxa de churn dos clientes está em 26% o que é muito alto , quando o aceitavel seria algo em torno de 5%.
Sendo assim o CEO pediu ao gerente da área de Data Science para criar uma solução que diminua a taxa de churn.
Time de Data sciences se reuniu e propôs duas soluções para problema:
library(tidyverse)
library(DT)
library(plotly)
theme_set(theme_minimal())
predmodel_datatable <- function(dataset){
dataset %>%
datatable(escape = FALSE,
rownames = FALSE,
options = list(dom = 'ltipr',
ordering = FALSE,
scrollY = "200px",
scrollX = TRUE,
scrollCollapse = TRUE,
paging = FALSE,
searchHighlight = TRUE))
}
df_raw <- data.table::fread("~/repos/Increasing-the-Retention-Rate/Data/WA_Fn-UseC_-Telco-Customer-Churn.csv")
head(df_raw) %>%
predmodel_datatable()
descricao <- c("indentificador unico do cliente. ","Se cliente é homem ou mulher. ","Se cliente é idoso ou não. ",
"Se cliente é casado ou não. ","Se cliente possui dependentes ou não. ",
"Número de meses que o cliente permaneceu na empresa. ","Se o cliente tem serviço de telefônico ou não. ",
"Se o cliente tem várias linhas ou não. ", "Se cliente tem serviço de internet. ",
"Se o cliente tem serviço de anti-virus ou não. ",
"Indica se o cliente assina um serviço de backup online adicional fornecido pela empresa. ",
"Indica se o cliente assina um plano de proteção de dispositivo adicional para seu equipamento de Internet fornecido pela empresa.", "Indica se o cliente assina um plano de suporte técnico adicional da empresa com tempos de espera reduzidos. ",
"Indica se o cliente usa seu serviço de Internet para transmitir programas de televisão de um provedor terceirizado. ",
"Indica se o cliente usa seu serviço de Internet para transmitir filmes de um provedor terceirizado. ",
"Indica o tipo de contrato atual do cliente: mês a mês, um ano, dois anos. ",
"Indica se o cliente escolheu faturamento sem boleto. ",
"Indica como o cliente paga sua fatura: saque bancário, cartão de crédito, cheque enviado. ",
"Indica a cobrança mensal total atual do cliente por todos os seus serviços da empresa. ",
"Indica as cobranças totais do cliente, calculadas até o final do trimestre especificado acima. ",
"Indica se cliente deixou a empresa ou não.")
tbl_descricao <- tibble(variavel = colnames(df_raw),
descricao = descricao)
tbl_descricao %>%
predmodel_datatable()
print(paste("Number of Rows: " ,nrow(df_raw)))
[1] "Number of Rows: 7043"
print(paste("Number of Cols: " ,ncol(df_raw)))
[1] "Number of Cols: 21"
glimpse(df_raw)
Rows: 7,043
Columns: 21
$ customerID <chr> "7590-VHVEG", "5575-GNVDE", "3668-QPYBK", "7795-CFOCW…
$ gender <chr> "Female", "Male", "Male", "Male", "Female", "Female",…
$ SeniorCitizen <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ Partner <chr> "Yes", "No", "No", "No", "No", "No", "No", "No", "Yes…
$ Dependents <chr> "No", "No", "No", "No", "No", "No", "Yes", "No", "No"…
$ tenure <int> 1, 34, 2, 45, 2, 8, 22, 10, 28, 62, 13, 16, 58, 49, 2…
$ PhoneService <chr> "No", "Yes", "Yes", "No", "Yes", "Yes", "Yes", "No", …
$ MultipleLines <chr> "No phone service", "No", "No", "No phone service", "…
$ InternetService <chr> "DSL", "DSL", "DSL", "DSL", "Fiber optic", "Fiber opt…
$ OnlineSecurity <chr> "No", "Yes", "Yes", "Yes", "No", "No", "No", "Yes", "…
$ OnlineBackup <chr> "Yes", "No", "Yes", "No", "No", "No", "Yes", "No", "N…
$ DeviceProtection <chr> "No", "Yes", "No", "Yes", "No", "Yes", "No", "No", "Y…
$ TechSupport <chr> "No", "No", "No", "Yes", "No", "No", "No", "No", "Yes…
$ StreamingTV <chr> "No", "No", "No", "No", "No", "Yes", "Yes", "No", "Ye…
$ StreamingMovies <chr> "No", "No", "No", "No", "No", "Yes", "No", "No", "Yes…
$ Contract <chr> "Month-to-month", "One year", "Month-to-month", "One …
$ PaperlessBilling <chr> "Yes", "No", "Yes", "No", "Yes", "Yes", "Yes", "No", …
$ PaymentMethod <chr> "Electronic check", "Mailed check", "Mailed check", "…
$ MonthlyCharges <dbl> 29.85, 56.95, 53.85, 42.30, 70.70, 99.65, 89.10, 29.7…
$ TotalCharges <dbl> 29.85, 1889.50, 108.15, 1840.75, 151.65, 820.50, 1949…
$ Churn <chr> "No", "No", "Yes", "No", "Yes", "Yes", "No", "No", "Y…
naniar::vis_miss(df_raw)
colSums(is.na(df_raw))
customerID gender SeniorCitizen Partner
0 0 0 0
Dependents tenure PhoneService MultipleLines
0 0 0 0
InternetService OnlineSecurity OnlineBackup DeviceProtection
0 0 0 0
TechSupport StreamingTV StreamingMovies Contract
0 0 0 0
PaperlessBilling PaymentMethod MonthlyCharges TotalCharges
0 0 0 11
Churn
0
Apenas a variavel TotalCharges possui 11 valores ausentes representando apenas 0.16% da base de dados.
df1 <- df_raw %>%
mutate_if(is.character, as.factor) %>%
drop_na(TotalCharges) %>%
mutate(Churn = forcats::fct_relevel(Churn, "Yes","No")) %>%
janitor::clean_names()
summary(df1)
customer_id gender senior_citizen partner dependents
0002-ORFBO: 1 Female:3483 Min. :0.0000 No :3639 No :4933
0003-MKNFE: 1 Male :3549 1st Qu.:0.0000 Yes:3393 Yes:2099
0004-TLHLJ: 1 Median :0.0000
0011-IGKFF: 1 Mean :0.1624
0013-EXCHZ: 1 3rd Qu.:0.0000
0013-MHZWF: 1 Max. :1.0000
(Other) :7026
tenure phone_service multiple_lines internet_service
Min. : 1.00 No : 680 No :3385 DSL :2416
1st Qu.: 9.00 Yes:6352 No phone service: 680 Fiber optic:3096
Median :29.00 Yes :2967 No :1520
Mean :32.42
3rd Qu.:55.00
Max. :72.00
online_security online_backup
No :3497 No :3087
No internet service:1520 No internet service:1520
Yes :2015 Yes :2425
device_protection tech_support
No :3094 No :3472
No internet service:1520 No internet service:1520
Yes :2418 Yes :2040
streaming_tv streaming_movies contract
No :2809 No :2781 Month-to-month:3875
No internet service:1520 No internet service:1520 One year :1472
Yes :2703 Yes :2731 Two year :1685
paperless_billing payment_method monthly_charges
No :2864 Bank transfer (automatic):1542 Min. : 18.25
Yes:4168 Credit card (automatic) :1521 1st Qu.: 35.59
Electronic check :2365 Median : 70.35
Mailed check :1604 Mean : 64.80
3rd Qu.: 89.86
Max. :118.75
total_charges churn
Min. : 18.8 Yes:1869
1st Qu.: 401.4 No :5163
Median :1397.5
Mean :2283.3
3rd Qu.:3794.7
Max. :8684.8
As variaveis abaixo possuem informações duplicadas:
df1 <- df1 %>%
mutate( multiple_lines = recode( multiple_lines,"No phone service" = "No" ) ) %>% # substituindo "No phone service" por "No"
mutate_at( vars( online_security:streaming_movies ),
funs( recode( .,"No internet service" = "No" ) ) ) %>% # substituindo "No internet service" por "No"
mutate( payment_method = recode( payment_method,"Bank transfer (automatic)"= "Bank transfer" ,
"Credit card (automatic)" = "Credit card"))# removendo " (automatic) "
df1 %>%
keep(is.numeric) %>%
gather() %>%
ggplot(aes(value)) +
facet_wrap(~ key, scales = "free") +
geom_histogram(col= "black", fill="steelblue", bins = 25)+
scale_y_continuous(labels = function(x) format(x, scientific = FALSE))+
labs(title = "Distribution of numerical variables")+
theme(plot.title = element_text(hjust = 0.5, size = 18))
df1 %>%
keep(is.factor) %>%
select(-customer_id) %>%
gather() %>%
ggplot(aes(value)) +
facet_wrap(~ key, scales = "free") +
geom_bar(col= "black", fill="steelblue", bins = 25)+
scale_y_continuous(labels = function(x) format(x, scientific = FALSE))+
labs(title = "Distribution of numerical variables")+
theme(plot.title = element_text(hjust = 0.5, size = 18))+
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
total_charges: Cobrança total mensal cliente por todos os seus serviços na empresa.
p1 <- df1 %>%
ggplot(aes(total_charges, fill= churn))+
geom_histogram(col="black")+
scale_x_continuous(breaks = seq(0,8000, 500))+
labs(title = "Distribution of Total Charges by Churn")+
theme(plot.title = element_text(hjust = 0.5, size = 18))
ggplotly(p1)
contract: tipo de contrato atual do cliente: mês a mês, um ano e um ano, dois anos e dois anos.
2. Clientes com contrato mês a mês tendem a cancelar mais os serviços.
df1 %>%
ggplot(aes(tenure, total_charges, fill= churn))+
geom_jitter(shape = 21, size= 3, alpha=0.5)+
scale_fill_manual(values = c("chocolate","steelblue"))+
facet_wrap(~ contract)+
labs(title = "Tenure vs Total Charges by Churn and Contract")+
theme(plot.title = element_text(hjust = 0.5, size = 18))
gender: Se cliente é homem ou mulher. 3. Clientes do sexo masculino , tendem a ter um churn maior.
p2 <- df1 %>%
group_by(gender, churn) %>%
summarise(percent = round(n()/nrow(df1)*100,3)) %>%
ggplot(aes(x=gender, y=percent, fill= churn))+
geom_bar(stat = "identity", col="black", alpha = 0.5)+
scale_fill_manual(values = c("midnightblue", "chocolate"))+
labs(title = "Rate of Gender by Churn",
y = paste("percent", "%"))+
theme(plot.title = element_text(hjust = 0.5, size = 18))
ggplotly(p2)
payment_method: Cobrança total mensal cliente por todos os seus serviços na empresa.
4. Clientes que fazem o pagamento através de transferência bancaria tendem a ter um churn maior.
df1 %>%
ggplot(aes(tenure, total_charges, fill= churn))+
geom_jitter(shape = 21, size= 3, alpha=0.3)+
scale_fill_manual(values = c("red","midnightblue"))+
facet_wrap(~ payment_method)+
labs(title = "Tenure vs Total Charges by Churn and Payment Method")+
theme(plot.title = element_text(hjust = 0.5, size = 18))
4. Falsa , pois clientes que pagam seus planos por Electronic_check que é uma especie de debito automático em conta tem um churn maior.
internet_service: Se cliente tem serviço de internet: - DSL.
- Fibra óptica. - Nao possui serviço de internet.
df1 %>%
ggplot(aes(tenure, total_charges, fill= churn))+
geom_jitter(shape = 21, size= 3, alpha=0.2)+
scale_fill_manual(values = c("cyan","midnightblue"))+
facet_wrap(~ internet_service)+
labs(title = "Tenure vs Total Charges by Churn and Internet Service")+
theme(plot.title = element_text(hjust = 0.5, size = 18))
paperless_billing : Indica se o cliente escolheu faturamento sem boleto.
5. Clientes que fazem seus pagamentos com boleto tendem mais ao churn.
p3 <- df1 %>%
group_by(paperless_billing, churn) %>%
summarise(percent = round(n()/nrow(df1)*100,3)) %>%
ggplot(aes(x=paperless_billing, y=percent, fill= churn))+
geom_bar(stat = "identity", col="black", alpha = 0.2)+
scale_fill_manual(values = c("cyan", "green"))+
labs(title = "Rate of Paperless Billing by Churn",
y = paste("percent", "%"))+
theme(plot.title = element_text(hjust = 0.5, size = 18))
ggplotly(p3)